#include <stdlib.h>
#include <jni.h>
#include <android/log.h>
#define LOG_TAG "System.out"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
// 3~6行开启logcat日志,ANDROID_LOG_DEBUG指定了优先级，LOG_TAG指定了日志的tag,__VA_ARGS__是可变参数的固定写法
// LOGD就只有一个可变参数需要调用者指定。
/**
 * 把一个jstring转换成一个c语言的char* 类型.
 */
char* _JString2CStr(JNIEnv* env, jstring jstr) {
	char* rtn = NULL;
	jclass clsstring = (*env)->FindClass(env, "java/lang/String");
	jstring strencode = (*env)->NewStringUTF(env,"GB2312");
	jmethodID mid = (*env)->GetMethodID(env, clsstring, "getBytes", "(Ljava/lang/String;)[B");
	jbyteArray barr = (jbyteArray)(*env)->CallObjectMethod(env, jstr, mid, strencode); // String .getByte("GB2312");
	jsize alen = (*env)->GetArrayLength(env, barr);
	jbyte* ba = (*env)->GetByteArrayElements(env, barr, JNI_FALSE);
	if(alen > 0) {
	    rtn = (char*)malloc(alen+1); //"\0"
	    memcpy(rtn, ba, alen);
	    rtn[alen]=0;
	}
	(*env)->ReleaseByteArrayElements(env, barr, ba,0);
	return rtn;
}

JNIEXPORT jint JNICALL Java_com_yf_simplejni_Jni_sumByJni(JNIEnv * env,
		jobject thiz, jint x, jint y) {
	return x + y;
}

/*
 * Class:     com_yf_simplejni_Jni
 * Method:    subStrByJni
 * Signature: (Ljava/lang/String;)Ljava/lang/String;
 */JNIEXPORT jstring JNICALL Java_com_yf_simplejni_Jni_subStrByJni(JNIEnv * env,
		jobject thiz, jstring jstr) {
	 char* cstr = _JString2CStr(env, jstr);
	 int len = strlen(cstr);
	 int i;
	 for (i = 0; i < len; i++) {
		 *(cstr + i) += 1;
	 }
	 return (*env)->NewStringUTF(env, cstr);
}

/*
 * Class:     com_yf_simplejni_Jni
 * Method:    sortByJni
 * Signature: ([I)[I
 */JNIEXPORT jintArray JNICALL Java_com_yf_simplejni_Jni_sortByJni(JNIEnv * env,
		jobject thiz, jintArray jarr) {
	 int len = (*env)->GetArrayLength(env, jarr);
	 LOGD("length=%d", len);
	 // jboolean在有些虚拟机中用来作为执行完GetIntArrayElements之后是否创建了数组
	 // 如果创建了副本就会返回true(1),没有就返回false(0),传NULL表示不使用该参数
	 // Android中这个参数没有意义，一般都传NULL
	 jboolean isCopy = NULL;
	 int *p = (*env)->GetIntArrayElements(env, jarr, &isCopy);

	 int i;
	 for (i=0; i<len; i++) {
		 *(p + i) += 10;
	 }
	 // 通过数组指针操作数组，数组中的元素已经被修改为新值了，所以没有必要创建新数组返回新值。直接返回数组名就可以了。
	 return jarr;
}
